import { EventEmitter } from '../utils/EventEmitter';
import { Color, RenderOptions, RenderState } from './types';

export interface GraphicsManagerOptions extends Omit<RenderOptions, 'shadowColor'> {
    /**
     * 画布宽度
     */
    width?: number;
    
    /**
     * 画布高度
     */
    height?: number;
    
    /**
     * 背景颜色（仅支持字符串类型的颜色值）
     */
    backgroundColor?: string;
    
    /**
     * 阴影颜色（仅支持字符串类型的颜色值）
     */
    shadowColor?: string;
    
    /**
     * 是否自动调整画布大小
     */
    autoResize?: boolean;
    
    /**
     * 是否保持宽高比
     */
    maintainAspectRatio?: boolean;
    
    /**
     * 目标宽高比
     */
    targetAspectRatio?: number;
}

export class GraphicsManager extends EventEmitter {
    private canvas: HTMLCanvasElement;
    private ctx: CanvasRenderingContext2D;
    private options: Required<GraphicsManagerOptions>;
    private stateStack: RenderState[];
    private currentState: RenderState;
    
    constructor(canvas: HTMLCanvasElement, options: GraphicsManagerOptions = {}) {
        super();
        
        this.canvas = canvas;
        const context = canvas.getContext('2d', {
            alpha: true,
            desynchronized: false,
            willReadFrequently: false
        });
        
        if (!context) {
            throw new Error('Could not get 2D context from canvas');
        }
        
        this.ctx = context;
        this.options = {
            width: 800,
            height: 600,
            backgroundColor: '#000000',
            autoResize: true,
            maintainAspectRatio: true,
            targetAspectRatio: 16 / 9,
            antialias: true,
            imageSmoothingEnabled: true,
            imageSmoothingQuality: 'high',
            shadowEnabled: false,
            shadowColor: 'rgba(0, 0, 0, 0.5)',
            shadowBlur: 0,
            shadowOffsetX: 0,
            shadowOffsetY: 0,
            clipEnabled: false,
            clipRegion: { x: 0, y: 0, width: 0, height: 0 },
            ...options
        };
        
        // 初始化状态栈
        this.stateStack = [];
        this.currentState = this.createInitialState();
        
        // 设置画布大小
        this.resize(this.options.width, this.options.height);
        
        // 绑定事件
        if (this.options.autoResize) {
            window.addEventListener('resize', this.handleResize);
        }
    }
    
    /**
     * 创建初始渲染状态
     */
    private createInitialState(): RenderState {
        return {
            transform: new DOMMatrix(),
            alpha: 1,
            compositeOperation: 'source-over',
            options: { ...this.options }
        };
    }
    
    /**
     * 处理窗口大小变化
     */
    private handleResize = (): void => {
        if (this.options.autoResize) {
            const width = window.innerWidth;
            const height = window.innerHeight;
            
            if (this.options.maintainAspectRatio) {
                const targetRatio = this.options.targetAspectRatio;
                const currentRatio = width / height;
                
                if (currentRatio > targetRatio) {
                    // 太宽，以高度为基准
                    this.resize(height * targetRatio, height);
                } else {
                    // 太高，以宽度为基准
                    this.resize(width, width / targetRatio);
                }
            } else {
                this.resize(width, height);
            }
        }
    };
    
    /**
     * 调整画布大小
     */
    public resize(width: number, height: number): void {
        // 更新画布大小
        this.canvas.width = width;
        this.canvas.height = height;
        
        // 更新选项
        this.options.width = width;
        this.options.height = height;
        
        // 应用渲染选项
        this.applyRenderOptions(this.options);
        
        // 触发事件
        this.emit('resize', { width, height });
    }
    
    /**
     * 应用渲染选项
     */
    private applyRenderOptions(options: RenderOptions): void {
        const ctx = this.ctx;
        
        // 设置图像平滑
        ctx.imageSmoothingEnabled = options.imageSmoothingEnabled ?? true;
        if (options.imageSmoothingQuality) {
            ctx.imageSmoothingQuality = options.imageSmoothingQuality;
        }
        
        // 设置阴影
        if (options.shadowEnabled) {
            // 确保shadowColor是字符串类型
            const shadowColor = typeof options.shadowColor === 'string' 
                ? options.shadowColor 
                : 'rgba(0, 0, 0, 0.5)';
            ctx.shadowColor = shadowColor;
            ctx.shadowBlur = options.shadowBlur ?? 0;
            ctx.shadowOffsetX = options.shadowOffsetX ?? 0;
            ctx.shadowOffsetY = options.shadowOffsetY ?? 0;
        } else {
            ctx.shadowColor = 'transparent';
            ctx.shadowBlur = 0;
            ctx.shadowOffsetX = 0;
            ctx.shadowOffsetY = 0;
        }
        
        // 设置裁剪
        if (options.clipEnabled && options.clipRegion) {
            const { x, y, width, height } = options.clipRegion;
            ctx.beginPath();
            ctx.rect(x, y, width, height);
            ctx.clip();
        } else {
            ctx.restore();
            ctx.save();
        }
    }
    
    /**
     * 保存当前渲染状态
     */
    public save(): void {
        this.stateStack.push({ ...this.currentState });
        this.ctx.save();
    }
    
    /**
     * 恢复上一个渲染状态
     */
    public restore(): void {
        if (this.stateStack.length > 0) {
            this.currentState = this.stateStack.pop()!;
            this.ctx.restore();
        }
    }
    
    /**
     * 设置变换矩阵
     */
    public setTransform(matrix: DOMMatrix): void {
        this.currentState.transform = matrix;
        this.ctx.setTransform(matrix);
    }
    
    /**
     * 重置变换矩阵
     */
    public resetTransform(): void {
        this.currentState.transform = new DOMMatrix();
        this.ctx.resetTransform();
    }
    
    /**
     * 设置透明度
     */
    public setAlpha(alpha: number): void {
        this.currentState.alpha = alpha;
        this.ctx.globalAlpha = alpha;
    }
    
    /**
     * 设置混合模式
     */
    public setCompositeOperation(operation: GlobalCompositeOperation): void {
        this.currentState.compositeOperation = operation;
        this.ctx.globalCompositeOperation = operation;
    }
    
    /**
     * 设置渲染选项
     */
    public setRenderOptions(options: Partial<RenderOptions>): void {
        this.currentState.options = { ...this.currentState.options, ...options };
        this.applyRenderOptions(this.currentState.options);
    }
    
    /**
     * 清除画布
     */
    public clear(): void {
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        
        // 填充背景色（确保是字符串类型）
        const bgColor = typeof this.options.backgroundColor === 'string' 
            ? this.options.backgroundColor 
            : '#000000';
        this.ctx.fillStyle = bgColor;
        this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
    }
    
    /**
     * 获取画布上下文
     */
    public getContext(): CanvasRenderingContext2D {
        return this.ctx;
    }
    
    /**
     * 获取画布元素
     */
    public getCanvas(): HTMLCanvasElement {
        return this.canvas;
    }
    
    /**
     * 获取当前渲染状态
     */
    public getCurrentState(): RenderState {
        return { ...this.currentState };
    }
    
    /**
     * 获取画布宽度
     */
    public getWidth(): number {
        return this.canvas.width;
    }
    
    /**
     * 获取画布高度
     */
    public getHeight(): number {
        return this.canvas.height;
    }
    
    /**
     * 销毁图形管理器
     */
    public destroy(): void {
        // 移除事件监听器
        if (this.options.autoResize) {
            window.removeEventListener('resize', this.handleResize);
        }
        
        // 清空状态栈
        this.stateStack = [];
        
        // 移除所有事件监听器
        this.removeAllListeners();
    }
} 